from M2Crypto import EVP

import hashlib
import hmac


def num_to_bytes(num):
    bytes = []
    while num > 0:
        bytes.append(chr(num % 256))
        num >>= 8

    return ''.join(reversed(bytes))


def compute_prf_hash(data, key, hash_len):
    part1 = key[:len(key) // 2]
    part2 = key[len(key) // 2:]

    md5_hash = bytearray()

    hash1 = hmac.new(part1, data, hashlib.md5).digest()

    while len(md5_hash) < hash_len:
        md5_hash += hmac.new(part1, hash1 + data, hashlib.md5).digest()
        hash1 = hmac.new(part1, hash1, hashlib.md5).digest()
    md5_hash = md5_hash[:hash_len]

    sha_hash = bytearray()

    hash2 = hmac.new(part2, data, hashlib.sha1).digest()

    while len(sha_hash) < hash_len:
        sha_hash += hmac.new(part2, hash2 + data, hashlib.sha1).digest()
        hash2 = hmac.new(part2, hash2, hashlib.sha1).digest()
    sha_hash = sha_hash[:hash_len]

    # now we just need to xor md5_hash and sha_hash
    xored = bytearray("\x00" * hash_len)
    for i in range(hash_len):
        xored[i] = md5_hash[i] ^ (sha_hash[i])
    xored = bytes(xored)

    return xored


def compute_master_secret(client_random, server_random, our_secret):
    SSL_MAX_MASTER_KEY_LENGTH = 48
    return compute_prf_hash("master secret" + client_random + server_random,
                            our_secret, SSL_MAX_MASTER_KEY_LENGTH)


def compute_key_block(master_secret, key_block_len):
    return compute_prf_hash("key expansion" + server_random + client_random,
                            master_secret, key_block_len)


def decrypt(decryptor, data):
    return decryptor.update(data) + decryptor.final()


client_random = "4469486520313333372031333337203133333720313333372031333337203133".decode("hex")
server_random = "5311b26552339266548448459a4edfa148d10ef339efb105fff8fb26bbb08614".decode("hex")
server_key_exchange_data = "0c0002090080bbbc2dcad84674907c43fcf580e9cfdbd958a3f568b42d4b08eed4eb0fb3504c6c030276e710800c5ccbbaa8922614c5beeca565a5fdf1d287a2bc049be6778060e91a92a757e3048f68b076f7d36cc8f29ba5df81dc2ca725ece66270cc9a5035d8ceceef9ea0274a63ab1e58fafd4988d0f65d146757da071df045cfe16b9b0001020080a840461e176465287dbb9a06da3a8a6c65f3b301c6ec3fbccc9f46035256429859638987fae9050230f9922f65a92fe9ab0ad1a2f9fd8cd214d728233755b9495b5d90348b656932855dd52d716765bd30a03083659a5e788368134c85f9488b18db203092edeacbf991b68e0e73b0035e597cead088cd04e71a1ab554534fd80100197c2cab2c46b36918b70be22a5258bdd833ff9d6d0a7476c5279361d611ef386942c3c311cd9656c743b88111231cfb3712eafc29ca7041bcaa01212d8f153873129b2ab630e4ee25dd620f45a086f30f1dc4bf6b1030048833143cc29a2f8d044020115c67bc7470a86598f368f2ec8f83ce215d5f1ad57d45dcacd330d92f4175cbb3d5b2b859a492be3879d2b9e59f1a4c07e35b06f6142106eeac047465f50e188282d3259c8b4a1844db0f31268a5cec08ec27e32610da6235ee281c77447672db9caa7019bab722bb9fd3542c1e1309eb0fee1335223a669ea68a09b79d6526954e7162966338330a565733e71713f2ed38518b8ac873a19cfcc40b7a".decode("hex")

dh_p = 0xbbbc2dcad84674907c43fcf580e9cfdbd958a3f568b42d4b08eed4eb0fb3504c6c030276e710800c5ccbbaa8922614c5beeca565a5fdf1d287a2bc049be6778060e91a92a757e3048f68b076f7d36cc8f29ba5df81dc2ca725ece66270cc9a5035d8ceceef9ea0274a63ab1e58fafd4988d0f65d146757da071df045cfe16b9b
dh_Ys = 0xa840461e176465287dbb9a06da3a8a6c65f3b301c6ec3fbccc9f46035256429859638987fae9050230f9922f65a92fe9ab0ad1a2f9fd8cd214d728233755b9495b5d90348b656932855dd52d716765bd30a03083659a5e788368134c85f9488b18db203092edeacbf991b68e0e73b0035e597cead088cd04e71a1ab554534fd8
our_secret = pow(dh_Ys, 1337, dh_p)
our_master_secret = compute_master_secret(client_random, server_random, num_to_bytes(our_secret))

key_block_len = 136
key_block = compute_key_block(our_master_secret, key_block_len)

client_write_mac_key, server_write_mac_key = key_block[:20], key_block[20:40]
client_write_key, server_write_key = key_block[40: 72], key_block[72: 104],
client_write_iv, server_write_iv = key_block[104: 120], key_block[120: 136]

DEC = 0

out_decryptor = EVP.Cipher(alg='aes_256_cbc', key=client_write_key, iv=client_write_iv, op=DEC, padding=0)
in_decryptor = EVP.Cipher(alg='aes_256_cbc', key=server_write_key, iv=server_write_iv, op=DEC, padding=0)

out1 = "066a7e4d8d7b97e2ccaa10793be207fc0530ee1c9c5a539e901f0d77808e9e4fcd892fe79cb411bc9ee622636fd17a6ca2ea0ab55b0f163f073bc8ea8579fe520646b41db9767626f733f84b17dacfdf40786f3faf9353cb3a2981fac1830a970b64be99d801979703cee3a4d0507904fe801829f68efa6d1611ba01a1d66605".decode("hex")
in1 = "32f6b96918882dd926d71caf41437deff94191ca1e1c9ecb3051bfe5ccd673eb0b01529e531bc881d21f54c93195de306b0d431750ed4a7eb1f15fbebcba363ccb18757e6c2a2f0e40e3f74a5d3f54066cdb5a0b761fe205c26f69bff295d5e7ff56d1418f16be83609b8ece2c5431db25cdc943b1066650895eb420a3b697510e04be43ac72addb84874843c0e868b305a0814faadd8a1d8ca90c8a71de15aa0503797dd0fb8212fc82ec9ac4f453a7ce7469df1d10e2b462a8e131cbbe701bffb4bd3b8dba57395e5a160695f6a57de2c4a427322c7fdd5ced1e046e663a5faea7cacd3db2332b6b79ff159ea4ed2306d81d8a90e89e56c3186ae0badf21847000bac09c2689453e33d5a283ce943866adde67fb3cca056625a54b23b8ddf918036ad65c94c2a9b192ad129909059a540e2f4c65ac581b197c44650d226ed1b2adac5d5642e0a599c41a3fbc5f8572908d123a475163375fd26f0d371864e6234415e8f2c1bc1e41a518fb699fcec3def015dc31cfef4386b4e4b745d9cb679b2b7b325cd8e57a4748ddced4870049f73645b0ac562326a1a644772017c72f869b2184a3fe2ab5a1964dc60ae165957392fb868f331fb5a3ed82ab940fa261867e580e5df75fcc395e5b0eee4435a714f8a4c1ab543191bc785520e166805b146f60cc250db32377d646fcf8eb6d9249558bdc8c9dc768d39790fdbf3940f016247af55deca567dcb95726b2acbe462dee6b9a460fdbf8d09e8bf851d2a92aa87c316479968d3eeb2686f6d2ad1923a422ebf14752e2832ea1cae1f76229e4d7a83ddc7171f6b7adfa2cbbb2f6adef4b14476944994d6db52df37572761f59c5f5a5dc27335c5a5edcc0a9d7c7c7fb3286c4ce24a382ba1f57e587270e69ab2237d4572294e5f5e0b557f4a6b706010a96fbbc9f459d9e6aa2f19c117e074275d3651bc1e194e0c678851ab7a338c3955cd7cbadd02e5afc27891fbb16fcb48c0b52bca35a6278876666dc5639845d616f3e1316664ed1b0d9ae7b55751fa84734bb1a3d70119453abe7ffa084d4fd0b8e7cec8ce54c0df031b59d40ab69c951262fb071df6c6260b28777278d6cd7dd51e96994691ec01e580f216078ccb8394159b51ae18e7580a4e69771b79c3f1184c2129a3bc5173e5c8af3d2bb8b6176b63289cdf68ac116a0db906596b42314ac3caa4679f7943efaead338af5744f07e2a599e20d3e5cce4aadab99b0affcda5c9d19be62dd8e2d682ce38051169b3dd7e848f273362edfc5f33269031403a68f16dc9a6f4e193d8b774e3d018a44f78d0b8934a9a19956cb0c0b643d3345c2d7492c500c4b5ff9a8c79db044c253a8e11033bf3e1b8aa5aedca7bb1dfbefe8dd882b9f26901938b63a55ab99397892acca087e36703578a34394d1700640bdff11f45c0d1c6580cf5d16b3f08be93b8640c588aa676217f51b17d9123ed90d309427440ca49458f7203cd6acb129b3f50c2c751711323ffde6e62307bc42eba34970e600d9a820c4239dd4f2abc4475b4b14eb42c22843d36d4ef01d93a8bc2688adc182eb3c1c683a01075a62ecebd10d54c75ad9628934b09a8ed6897d025c0002bfdacb63486bc0b3b3a9075265da5725dd76f571d2ec702ddee0c852497c0e5e42b248d58bcebd80c34c41679efd4eb1d380c7ec500a6fdb213e043631bbde9c8633b9d0194aad7fcb9517770835d96292e66bacfc3136d8c456bbe0c22c17369cf30546ec12fa7ef52a2ef440ac2e3aa8460c5eaa12768d5cfe19ab819e79162a8546e55a9cb2dade074c554036a0b060e06a6c44c1165ecd73df92885b2f21e484d11546f556c5113ae1d15b8e2197f53879b880d83ce7de447d42ae3c092c6532902074e11b5a0e3c33eec1a402284da7d17cc4a6bc423e527f197a89d42ccd1d1ecc80e7bc50d0a97f76a34916724155549db1d01b6e8236eb34dfd0cdefe97209a2508202ac971c3450a7597e0176021cffb29a1bf0a0c51473624f45aa8f5cb42f20ca1fa3147b3b69ca7136ec256f1f0013357a3cba480ff2751e00adaded9a7c5eeb7a965caa2c5316827ad86bf23c4cd3e560da7be8a8d568c8d20db6b3a4584ad1630ec719b4fea696de7855beb6bfa58347873f7953351a9b172690e7999275a7c86b7d328382649792b81fc471a2f6e310adae60bfabdb3243f85443e69c3a559e0b543b85a6473036ceeae52e35502b91ddf66cce2b04252694fa1ab2851c0066a16d6694bef22cd82d581515075e4270fab9905d79b991c7d5dea8a18c18a5c3ac51e1e5968fb8696ecc86bd1ade240853d7d2925d3f1d722ebf3d19be80e0b43a326351b5bdac0faf835776eb8480b6993d1f05b8e06dc9c1379d249afb65d40d856c36b763f22ffa170708e18d231a57fadb4d1a281484c950bb3fa7d08d64cd7ac93590084cc0d4464d47bd644949015739592826adb72a6be35aec1550fd7d9bb6676e2815b44a4a4ab964ba0e3c4a4bd618bf80f3a15d513c971530613a2b1cb8439b608e0a159918fb0a4aa6ed2c702723c496b771b8313c92df8b746998905f173e518e79428ddc3d66dec63ff6c292b3a6c810b9f4c9dd19c3967405ce5ea5a77fa39788f3fee961cf99ba5b6a748bcd24c45237faf7bbd02d88e7dcb3871af4d612669fb4ae6c0566b18c8dd5b70f749385242541f0b8c23fe1715cb41b88a7c2df1e85db13308272c7d75ee2c86bcad78a78cbcf19feef93ce790f305f47b29b678513497edee27852b31e7caabf893f8755aa57f0b8f881f1d49315b13b3cc31b91d561437fc3a67a87b2c89f82e7b734a521590cfb5197854104f46bced1b9702e269e18a14d1924ceabbd5741c6b48ad6d2179d0d31292efa83389fe1ac3494a37554523c6c5631da5c1a33a1284569b44e0b47bfe5719c73416517166ef53d43d021c9c9a31a9e3c40277af557e80e6aeb5e0d261c84b93f8fb22d233c22f9966c32a9abe6506fc399fbe4c0aa08aa2936bdcda1f77fdd8f540ac1847e9d396900de32ee721fb7e93399b55c26a328f725b4f5b15d279900c995d0d2d59372a21dd4fe13763f879c58e83ebd8ee10b8b6f2c06c4b0595dbdb95b6318158cc9ca316d92d969615e8389215c21f1611fb848f69e0a4220892f427d3f0c676e2a471167e81efd9bd9af7342d8bc53ce587cd78b57f9de41bb4bf95cc2bc8af8255173c7197c98cd486513b73d8c7b8e1fa7821e83da6aa78d8fa540eff2c397cf206408fc6a3c37b17ee3e185b53a78a23f91561f4d0f67741e39d764c1706696f37deb3d0918959cb779899aad00ad273ba08137069d93253892ad35470d4473722c2200a0e8435198502d924587b8a4b25a41157bfcd00c77061d8cea397035f3f6f84356ee89c6c07b06dc557bb1c158e7b2a219b4fa5fcdc7d246315769de1cf4cea57b0398c2380f6b48ac13bfa73852db9c67e69916864e23ffc32a03b3c64e47cb943eeebea21bb7100e6205b3a45f9847989fad51ea426e3f9b66ceb936d6d3c127593b90874efc37ab50b0edce0fb2adfe19aae527a8890eefdc297a4eadf97b25ea8bdf0f6a44e512407174adff085dc1b0f847d4ee19c65b7f11168a7684934eb9d63afa29fac66a51050f981a74cd05e2e9980a362bc698e359b41bc25154f0cacf066de2fd84972a6c7a67aaf0aa6595f3c6273bbb9c39557cccafc10c64d790764fc9d7c390790c52969edecf37d2c2fc81e77a7aa096942b13d6f3bba873484c279fa89a497aa52176365de31bd414c9348ecc35e11f5b43d02270cc690376334d2604ca38116d97375e33b6fd02a6dc2f49196cf785fc252ec3a6f97354d2ba2a3b43a038d054260551f4d794c18c97d46bbf3f2ca0500f33eb6dfe32254a46deb503de6c07fda7c82891f9e37b75fd30c7e1d44e98660612a36cec6d4c659f71ef4f3bfbbbb8d1f94c18b042f82a96683d2cfb77036473cef137a65a7aa11c1c5fec2a7a329f25f06824f30cf84d16016681808f9cff937d661d075130fea17e0d2932ae67b81068c1f120a0a6287870f9b387feb54641f9498fa7f1e9ab73d79a7111bd24599ba4f27afb1866af747943ace7c07bff9baf3aba969182c5312ac9b489ced4fc367dbac306734bf420fbf222768441d1524e851374374c31158719a044e053691a71ce64a46f90449f2c14f8d652491393fdda709346ff03989543c499f4d8de136a5c96ce86daec027e91f9863de5fc54d6ae085bf0ae814ad421922e07ea7b95af1113c9ba780ce4554a679f092e5721a5c22c12b47de254c9e0828b88adea3e6ceaac897d3c8197d3a101bf2838244149eccd9bd5344111ed0d32a36e5ce0a54adb2b9ab5e8d0db39758f471d043c50b1a669f690dbb45f6450dafe738535208b7a394b11bfb475cb95a40d84c22b7a85bfac56a196fa63356747b181ca369d7a9bdf5a7affe7f096ec475bb1a867f119de36947e4f125b97ef57c1ea42be688f32d789f9ea45d4e790a00b3546bcb79b957302bb86b00c87e5919e611439a494bfac9d7d3d3f291896cb5ec49cbfcababeb65efc1fc7d73b2e6f3a90481772f032e4529ac1d4f209fedc43e5bfe2e41d279ec608b833b579c7d104877a9e971c8cd4135e12f77e8123f7f989dff6036441529c662c25731c8db1231fdf3be6872391e791422b50bcf29272b88684601f02d6395005c06fcabe92e58f6e4c1341ea3fd5cd9a5bb22d5387e21aa81431aacbdcb47f255b269164373a53c425432f037ddccaafe5d409b4d33534c03048a2bfc75db75267ce9f7c9ae47298b458b83d0369bcbb4dabd4f176c1c708c744f80dafe55877205ce6ea9776c732edfdec9646db7c0cd8ec6f92942b445b48d7ace8d12902675a624dbf565a56af01a18ff334e68091ea9ba05d97659bb274fec872aff98f54e26987c24ddabce2585cd5bb3c5f5eb74dd852994b87514c74b40ed22cd155917f4554a677a65329dc31b95c748b697d7a1d98d5990fa94a452f235a3c8c1b6de96ded7e57555f3afe4fce8a9439e478eddbfc33aa5e34d14caf8c780bc51f7ae7abe09b51b6eb058a5d7a18662df7fd3d55feca9068913cd801cc85089dfe730095effbc6a4c022c5c3a7dc003175ba893ed73f71ec2f3e2dc35e1ebc3853fe03a61a881b853985ee275071ad59f1e6b0466764377825dd22396476dc989c35b3ae1f9d4feac98cb1cc5689286fac5e59c3ddd6efe8e0c2876d8249f0da721fb987ad3739c0b6c8d2bfffe721e63c427a77a3b9f28bf43b9a95343d7e473a83aa2cbeadfa295de229d7e293d1109fd979b93d58bfefee44a3d66c58dfcb339ddbf2b766fc11a99b7f577bf30f05c8ef3e714934f6baa83d7138611cc71898c3e67ad185eace36b82663d5de08d4114da6b52c2dbc014c5fd174ab805c29b1c568d9c443ac2830c6b937b5de975d14b03cf9d6df04de25610462c719556ce3beabf04100ec923d9ab65cc6311ab00b891dd5549df730802538bbbfe0f75d3ea407d989ccbd823c828f6dd2216eb517d082b5bb0c923e8fc0bc0b01a8a7f0842d8ec624fc3f36702e5613ddb2824412d1c49d6ca7ebcec0b2a910e7dbeae242f2c2119630bab9b90965a286ea8ffc1269a92e480f8e77a8e5b60520957cd35429b143e4fdc75644567ad440542b800ea14df1080f0e7e95f9b14bca47244afa64916d6aa45aae61f65213c55acea4d9e22c887cbd919501d4f6de51efaa54fcb55f6b22bd4dc5dbfe877ffe29262cf39e5121f2370e78be6470646fc28e71f21ff0761b19aafb72ba9feeabbe4bd0381d80d8386573801572e8ba38a2c1f0fbe0f32b07d592ee85b15461a0440a02f30e575969bf5e27190c44c614d7dacf59d926dba547e9bcd5dfe44470146ab029f6440f39d8ab8f4f2b072f596f167af6f79702df1893631a025593f7a1aa7a706a45be31a8249fbe196265be9900fec85c01c8352915f00449527205926636b4dd984a79bfc91ddd387f96d959ac70da76c7ab8fea287535ed129b3d437529aaa24251546b30fcec6cd87c91e43e8f4f47966b4b07d822082fad59f77acf6fd46c4c08387da107aae424307770e4c1ea78310a630540657c80ccebdfb1a9f0fe51245fcbfe2102ad7d5329901bd6e614f243aefe84f490021add29a49db8973ab967d20971f61f99ed30126ac80e25c030e8905521f00ce282959814365f9af66e7e31460a46cc0110068d21b901d9741c4fd144f99a6d06d3326ff0803669545a9da89a05de252f6e790b5b280828a5aee9a3a07c915f0b1ca60fc0efbb3fef9caa86e70ebfce0cbdba424e336fcb1df54b10451e307ef0dd13b750fbba41c5dddea022f13bf634e611f6583e9b7328fb2bd69e98321f93b3add35d34d1f674d15afb8ad25a3c4a4b0c76356a1f655b10dba4cc146caf33d3e6adc8609affc886663704812d9921dc92d02e7c9a845804be701c93afa482ad52139cc115b520e3d4c4f53877d44ef7b7cbc750088566d9456fc08e4975625d8d63e6ab586596dfea3effa06e81fdb7b8ff341dccea5c12cab6319f2d9c3fd8fdfde9f7fba1eab77a218ac227d53fc38f4869da72951331257d38c0f095f837773b83b33971d33000d459195d01d7216f2c99105d5e6224d8ac4eff63420f05f14d15396c06e44aad3f81d5387255111cb32296a5e4faa6e80ab78079c758e6d027a480886762a2edc70b71f1171266dc586e236e0bfa45ce38cc6020e466b8ae143fb71edbc54da3e1be848e9b5e0d232f60dd340afd79121b43aca71e8e34584de29e0a685c50ae19faab96f4edda007e8773010f35632d09de36aba4f421e2672f2f9ba2039a8a096cb09272e55148115a5d4c92ddd7ed5987f2b4feacaac0aa327449f49f126c85b000721ebd79cb176f5989e72ec8e1343925af04f83eb10f2b134dcb5a7cedbbae48f7cd3e80192841c3a75025997e563267775c491e50ae7f1bd17616f24c48a5ae1a189fef9aca2fef2d45910f93ad87f1d0e8ee4f49e95745ee18106a78cb206e20a42bb42bc9c42fcb52d5c09176f3380cc0e983e9907e07966a28a5fcae5acc8f42711c73842f22afd52b0f2961bbdc141543ad4d46b527a6388118fd4ac019c9392f15770269b3261abb20d98d217e783d0b02e1ab2afe2b2b64ca9346de91e11f608cbe78626908be76e52d79c7188d002db6e67c3d2ced04502736acf44a1d237e95486b8286c8b7b01b3e89377ed991062e92e92a6058425e870e18de3971010e5699d5d36d54be28924285f4475b78beae176add225384d7e5464b4b7873fd20c2eaa1b7ceffc94648ab7985e5ab211c1059011a631182063e53a0f1483b54f6b55ec1cfb9035723b3e4b61108a671fb20e980ab58e436c020c6d8e9feaec76055d281309d90527cd61ae4904cf5d7970c50800930534dcaa541e4a8891d25c48e2a56d4ac3a324ba70eabe60e1a950b17a338e472ec4b70423018d99c0d72dde405e146b4cd35ca58448e95f410a4bf41e3c63853310fa7d6752ca3f65caab372b6d72755a26ef551cb5c2e7928692625251c6010038f20e1b6eef7ff29aff93cda60552b2852c178225a723d43b1dddde974f31952352c362929bd85671da4332a9713ebc1b73ec615544011592394e80cafd2fafa9ed2e511b98280a16576943c4cacbf84f3a6f5fc629d91b3612ccd221bd0ab15a6e9ee7e481638e00aefdf258133e50e32bbf511a00c135b30c0155cf1c49ce38469307ba005800d16af0c9f74efb8f0328e1dd1174ecb6bc50990488d507b527cc33d9fe1ab73728f92db0ace819c3f4ce3f656d2c0b8cef3ced97f75a8e08272e7fd079f3db383ced135e20d050223ceb6171714d59a4534d1aff3937ee1f3e89ee7fa49aa4ebde1afa3ae87e773f031fb4f9b1a676a089e8099cb428077e73266ff8ad1c0e299f0823691ff0071653ea9a268dadae35a29e11bd205c1bc7970e97c9f07da7917c94859510".decode("hex")

out2 = "73c49a7c487de3ede7d0d410e8e21af2125697939a77f913dd85d06eeff95d0685b62670c28d22f29e8c26bbd89d7cf5eafedea403d1d47d523d2e68ef61e3c5f733360ffe5ec0a188143d2ad6a4aa491fe8d81a39f0346fbcd135b655e5a23ad85c498f31fafe416a6cfecb772b2210414d1a5f9aaf2bbdd81cf124711db2036e101f2a16c8b89f16667afe9582bf1935ded2f2e4b31a4a6ac1b6c236d5cce3481a1165157dc36d7949bfbe0f3bd27d475cee7395342b089a16cdb0975bd065dbd3f0f772e5e279d66c9c7a5e1058be64d9cc565f66d7dc6ddde532a4b303544b9182c127127f12085ecae68c038f36ccdc6be8ba3af7c9b10a4d56d05667d518355bca36d65d072d1be5052d5317a65871b53498f8706bbb242247644f970c82840dc76bc14ee9d337c3dbc38fc75872b52e2fdb8ec17fd1fa217a10225186a1653a69f0279ac51f08e1e5a82a61ac569fa3906ab4ac4ed2d6195d457a6dc29ffd4cf08df09b7d2d9cb93b656c6215f6943e5d8a7af5c77c2b3d1763cde661d0e1724cb88e5442e6d3e08f6fc406c001a8792eee528bccdb93430d323b64296cd222f77465f5c285912043a89f829d".decode("hex")
in2 = "ce1bab4428f6414760bea59ada0435fda87628dd9eafaacd07b93cf55eba72754871d57ee0fcf3fb8d7fd1a29456f334bbecc270435f29bae30d503740ad88d6b80cd6bc84f1f5d99ffc1f0d8981a1663d51f8283c7ccc30aef25785618a4d1c542105d3dd9c04b0d3917c06946233a3abc6d7f8f415eeb8658e3aab05480aaa3952041342d02af37d11eef1d8d2a5442e1d2ffa55a095f332ad1904a0d0b04df48066a55abc7ffa29794b3fe0254e607f6cf29369e8f06ad5ad1010d1bf3dd791f79e0953da86346867c651100d952b1ba579353b86c6178264ef89645c0e0037fd1ceeef15b32e5c591b25db6f8b1146ef653c0a8daa6e4d5883986b4c095e831475e12e29d9d80db368805139b1672707914ee210c1233397d60d23fee3a64106da441037360cdc7d27f4cf4ca50edec87f9276547f8cb56352356c14a0b9d296563656d6032cb7319851d3d6ce4488246f5054af93f98c65d33cff906833123c5ae0d31df7f5d00fe0e6d514884e86c823b0e27e1138583ca82abffed32d1df6cf8eac07829e93f10419483274e6c648e56056cb25074188fa4b8feb4ecb8ad0b8e4185da520b39f66a48c5c3be7ef64919931ab8e2cdb01352847ba9736937a8381485763b42c3695aa1d479459d1a7eb65b2b470033f43de2f48bf6fe7b1108212a8014626575acf1a57ea7b2b642bcac729105d605caf5cda26edbd236158f10b92d45901a505b23bec13533941c551ff9991538a0f60e1db36497bd2f41026bcb5cb1e1b79bbe741fdffc7f886f92a02737894b4783fb73bf7820e9eecd3eabb138ebce17d9155171754fe1e3f298436902ff7aada4331bf45109b9511840ec8e81d1f361284148227dcabbfc46992a35ab925b68de770c88380244f6a0800e7de5bfd362d198d734da63680929521d676ff6488cda1d2fa5bf9673e927ee3cccb8f372d41f66469f53c6106ebc5d55383dd1841cd1d2d3428c17d9a13358fdfacde96d8e0ae2d530edc6a53589f13a34a35e116c5e758b0fa9e26bcd412450476fdfc7fa53dc230da25ee2136d1544465a810c68da236fe1cafda8ba23d74a9e9d0d9f7edd012d48f5f278589075e17387ce40e340500031288568797323251f284a660ed3d7c15416cc51c4c1fcd1249dff7168d6cf0dc6d6f2e14852993f58797d7c2b55185e5b5f476d75bba13583b46882d3faef1886cc5707b97b89f6b2eb9b2d1001737387bdc7f408292dfdb760263990663b080e27fd929e1a5bfd2d133f38462fe666226fff0b6e084cf4c2a12005bd2b57e20ad563f544f37934097fb5027592b2be4b649a8a4a3cc5b0eddee94d3c4ae110ba40f82afaa03d0ea559cbf4cffbd7d177189c362c83cdfa195758bb2689c54b49b61e3ce45a4a80bfe84bbc0013261f975c6d6d14fab457ab6e0067bf4b5c2c0c0ac09167b2d1cc26d6af22144b473f2297d54421480f057eb93e5f9b4cd27eff84bf763648edbf01b8661d51fef65012b7c76bdfd20eff8e91fda46da1316d64d54b14038e6df832e51047d47eae1aa90d5c9292d1052508f2839cc1c969165c27d173daac49bda4d81a055b5516c70ca4515fe058a89f07164e1b2df14d25d84167c57ed9b59975558cd4b09c9ea1cc56b8deeb969f4779f61a74460f63c418d83ce79dcd629f47f0aa8c936caf801934333f6710294099dd944d51485e5071295115dcf302b333f382b8942f73faedc6545cc1c95f32022ca5811b234ab01448d5a288bd022bc8fe778f3f184b9ffba7b1296638839fbd042e71441ee28baf620b79409665d25d9022ba048127f6534a02cb436d2b3be3ddf5ebc4664b9ae7e9f133f4c8b94708bb1da11e076d8b35134138981f22b933efef11f86c6cf1edd47bc2f4a025e29f675862444e947c2f0615f0cead76bb1d93525dabdce10431a65834579598907c0d73c392135f7d5dde4b093cc1dfdeea8054765469f88e691036d043c661463ec4b746d5cc30a98b491a458ac931d7e71ba258e7c4354fc703efa45efc7e0405ae3d409f7b3d4666a77b3f5b0f92df756f98d4989264e4b617d761269a835e70ff131e3c375d3bab695d8c30b359e1d7dc974c2f8e3bd50b3756a4e5e1da4e9ca36ff62bfd2f44e0c4c4bce7493975f117b5814abff96cccf21d157fa559974a7bb53c149757416fc02ee2eda13655b104f36e2a335322f4687da6c91e4f2dd126774fa74eff82abb8c67d00737a2dbdad37a989dbe0fb4aa9b5220506fa6335bc828a884c8ac66e9033fe48b08d70d36bfcdca25503bc4c8902416cffdf29f0ae2a83960032675ef2f65f66ff21f6df172454a8f811ea961cf18b1f33e66b2b89787efda260a33d264c74ffd00bb0c9586b368ab6f275b77897b53159648ec8e904be365a11d718432b7a15e1764eca5dd5070369e3f292a9f6900932b0edd70f16858686ea06a2a16536534c5685531e236ca498d97930881403c534a6e2e4003104c10036f35fc5a4779090e1a39b5f14387fb39460384991baa6b5eb3f6686f4e10cc84a37c39515126f79926205f204902577ccea6a712cecb96ce097bdffcbdc190caaf7cecfa2bba449fcaa605a2a61eef89b56090cacf8e760aa75c349cf559b630f40b262a0ae40ce2706a59f1dda20eacd4b5b6918990ef319d2c7542eb93fb8d828c75ba57e6e738edb8127c02abef432aa1b38a0ab2fade92c87a42f7e721aed0f54634814df454866c7063bdd754147ab592b2a0661e1a01a59502b343242c1cb95427893e09d8b688e380270aacea1839a007473b82674d4da579c0accd000f84db9ba43476841e8138dded8b6088693d5e2a37812a587a6badf24ebd8a463967d09b3b3de066c3c4df6bd54ba42945243928e4cb01e9be0554a26dbd744879a791ca548c8f57af72c7b4c1a52b543748f0043dd596e56ac709cd08a3a497eda6408d40c53ef06833178a5a0c39f7e4231548fb8212acf734ee820ea591ee8d7cc29430d8faecdb8e1f5d6a02b37d3cfbcdecef84c1f501721241b51c17151a50b47e493b46ebd4b819796e7764e1b946b0f22e38161b22e2380ec0934584667a2f7d67d5d4c658a9b5ff4fc95341f67e3b74602858e6b56147e4122379de24f15d470df731d798eeb3639c29bb11abbae80e94cfdb27a66f2919169efad77ed180f7f2cf82fbf039bb79b30544464ebf43f6b9f97d7a8750c46802192c0196be28fb8daebefc9d9be42db595e907a0ef6e98677d5b3250c73cc087bda1339138bb4745f573c6e7db0b692d087ead46036be2e402bd2eb8018d18d329ffd5dc1b7ba910c97e738d4098b958ff51947b716b7e2fa6318b17d771e1707f8ecbbcd6485c6f060837a24f01ea333bd2746ad2cf83ee4224e17c1c4556fe5baaf059c37c9d3877be48ce67b8b709764d88f8a6efef354e5b74f0f1c720b4548eae29918047e4a4df3103a855a628bfd3a2e7c4e6fe23f17e37f9aa36c15e8ec13eda8e8de5d962c8432800bde6b95fe438aa036702b778ac503fba0d14be6d430712c6a1aeff0a5c655648a2129648999a91fed3377cf8fb9ff0020bb37f010c3d5edfb233019aaa09d5d05097098857f1450664adde09d1ab484849ff0600bb8819d93be24953e9b6d6f942c68343f19e4740f0923b2fda52e802ce384e2d649fd83d77b7a8ca23d36e2a0b1d4c78f622f5e7c6ffd5e2210d5db9345aa70d5f2a336e6ed50a237dedff1a5fb9a7016a0bafef2bb3f00188e91b01a3f32db3aab46746ba80b85c77b751c82ad8bc689bb0de7a7ba1c89fe0a0c53cf3665a78373f86d62bd7edf97a889514548fd45f581df9a7ea583522506aa4c9b68273ad7e56d5b55ff648b6883b7c2ffe76379ffa5f699741bf603161f8724fd6cce85ff8ec87912cf8b3ffb1d162b8e481b65e968038ef4221e64c9f43033cad1677ab02526231f4a64c377cfb8f1d6d1bd5298009c43f0dd3edfcc25e7cb54cf56294da913d9444b6c18c369f8250e6d3cb1944127cbe223920203c8fc5948f067a15fc61c69c6f5c8e8c6ba7e847efce4b31d3a7e244f833c26d10b559780e1cce7e4695b0852d5b274e5dada6916ca043ff8725bd780e9f176d1dd56aab2e91844c95deda0687ba64e681587fd23611445bc60d2ca31a42c64e80a94dd5ca29049e512c5978447bf6a58d53200f4b1c1239e979cc69e6fc78e76e2528603fa2e4f31bff4898b0ac17d1535dbbaed24d8f0cc105c4f5aab983bf0c3bac6b5397bdb4ec9083056791aa771475340c97c186c1aa70efb2a7c35818a5b585ec1e1649af7e729f4a3dca5951c767d8bb2580f61b1afb4609ab496cf87b7c02061cee971fc84b98cb8765672806dc007ca3ef89a068ef1e2d7a0c7273d3d27ef76d41b95f27941970e04192e275f772606e04673c1e7f315a028b00cf7d9233031f7ee14061d0fad5f348af6c79bd27b76253022777b758cf3b651a4f5f62ca89de247607d72b6f5fb3692d62263e38f154880a000ddad52002c31b4fb8b89a326e8c16fac68a86266e41a3dd97ed137f801121cf1f0da614a256f27f714ba7b9ea2fe03ac005f70bd22b12081418eac9e4798bba9f5e3b9ff94143048e19bb0f351b6096976fe8e13b5dba4965e9711885057795d0ef11cd97e4882733f2308d28182b260553eab56e0ab56dee0295938ab1117d545e987aaa5292bad2812ee38eab2277f1a36f73c03a2118619f121d94578ed719160888b81bfc946b662f5394bcd564001092adb38295db7e7f23537f917146b8f47780e9d3cbfbd9b3837f3f2b09aca065cd3156e3de70c451268045159dc1dda40ebe6537002dfc7314214b69baac29e4529574250a2377fbff7c7e73e37b0648ff74232235682b1125b10b50720c80786ad384cdf9dfd1638aa26be224e527eada4640c5acf79afe2e10bb88871434b7f3fffbbd75371e0f6f76d7cd7af98418fb7d2cfa8bec7b41ade833d0c58d7490609f41d8d9a314d94f191f8bef64903fde17b8b41960e7a573456d960e3b64ed40601214e6ec8ed1dd38e7ea73ff9cd42fbea3392e0e3f73fe5c8f8484c4db96c213aded372eed0b972d55051418fe5fe4477268ed59c91a5d312453b4fd899353f614d005a18648696e2720cf2e9805f8505d0835bae609973d6de10cfe3829cd5bf119b81e9a578bbabb810550b13c4eb0325e3ecd84fcbe3648c0dcf2c70793a8eb5256190a8fa56631797463771b91a595d37f558c7fab890037e6acf536b129fcb29c303418ebaf72ab760439715304cc46a491082fd5fce571be9ee130e4620262dfd5493ce9790b5a72b075b1065aca866fc779d6ee82e00f97459e7d12f984de2d6328b682ae7aa9a014047889bb3ec58b2a2369c54e9de6a824eeb81c1c499a7d85a1f305203f273b8b907bed399ce67114620b34198e0d19bbe0966c6665cf136e9a115ea0cc05ab31ae5c88807336efe419a36f437a653d6fa2e7ac160bc771e4f9f51a7ba83a44de477c51ac1aae61b272702eb6125decf905bef8af3529b4f118e8638357bb713169076c97ab3afd2e1c620cb9dc15b7d32c9192f84c62c7dfc0082898122d6fcd3f54c92c2d5a6fe2105d81720c6f83b9bb45bc6c916de03bd1c5fa48831ac49a90125f733ba0df456ef3ff60bee8088ba2afb433ca22756bb9c6e7b130a86b0ff213d61942bf59c4018ec8079b72e3d45ac4a7764db96739a6a3743e0bee35ca7fa60849913293b0d4c2882715f91158484a1c7ecedd6ba4cb43b5cd89d81a12fb9f374668195153c369b58af1c0df20b9984b74737c7c89fa9a2e49d85c98764dc2a0ae1dc6bfd2f4e5ec332c707c9fb53586713fae794322977890572649d964c54ac3c4bad84d42ddd061aeb4345a31a426a79c14b0f26499fcaf9cf298e84430c3b2cf4338e4dfd8ffe0e47f3c6293c8ab8279903fe37d6f9a9ee3edfc1b53dc713faea3ed8e561bc9205c02573ecc7f6c785a0565d68c614be5bcf038dbf3e85ad4cb050fe42e7800e63d4597603a0cd75acea09ae174df364887154da6b8b9419a6079796787f9865f869af12cddc6c2fa520cbc4f2c20cb7a21e0c6265e3a5da18368a5b6cc5c293b35d78d715c069aef40f7d498784bf09d97dc7f1fec099ee3bdc16efe3d773799142b5e6335ccc3f6a22635f30814a0ea4a71367b25b6816d9e586edeb2fcd151fab578a976a36afcae0d8e46500cfb9047c188c56bae96769e0673fe49fbf37c46af6d2b481a8f20c374cd2892c83caa1f15384750d096a55f9a0aa20409f4d82deb3b16d11b071728f14ccd7e44eda4d4d82f71c93d493cf8bc3373ebcaf96aeb6e6bc94930be50018b119f878a72e6b9107c8f6faecc02bcd32c6efffea8727fe0044e65eea7eef924eda73e6d2ab34a6af88c979845b16fedd12bdbed595aec5d927f7dc20fd581c4183163217279d1f850e3b4841036bf7f36d33086daf4cca8c865a94603c4ad82bc116cb483571b66f94564684abdf654b9c2c99e2dbc9776b2d6e754a02b81603bd98870df669474f2911e4dcfc1d778526bcc6012f4276ce39f3992e7e8e4c7fb19840672f96c0700ccc701db5a3e6856bcd7ca32fa79ab230947e11f866b96ca6122874c0fc8ab66e6090ffcdc37ea76a463b92f0420a02b012a84814f713a6d61d4ff0739ba9240d872509deac749e27a996de13eda5a38a63e611e14391d6ece69411b22e89f1f6b698ddae3d1d2004c055ca7d631e063d7adec3adfba032f4821e2e86d459666abeadce6da6649a3ca9cc8d82fc2e851651299b86a4d7596a9b6cc0224f355dce27b11009639fe74832ffe4ff86dbc5407614d96152442357b78d4776ef64350c454663d2088413874ffd079c5eb7df8a49be1e5cecdaada48e58ab4ec36b6be201bc72d50f13e94c2ea9719018b6bf65024f79d1c4d8af8291a918b9ead4f74c1c3e3c178ff8f73deac4e51738a5084b0bf180161f582e157d2dea1b81d6a046b0f4aa0b85d97a26034cf12dc3545c9faa00d90836cd43a7621bab7b1e07855df984ac6058961467c78f72e26ba04813c2df5337e86acca8db3616e6b6eb7a2c3e12f14f397e8e994b37971bf34831bb4636ea7ea181929267840998e529bce86b8847c7a33af817cbb1f1aca4025f1ff4cf417dd9e81b3963f22ea348256e6082291f9fac152592cf7cada2521ebeb007b9b87f44194b2cd8a86fad4265168a0449014415d11e71d650006447ef4a6a52f351c78130a091115ea79192384e13d99ba43ba9999a7e4652f418e875c8aaaa47dbfb5845211d800ad461f90d1b210f9b837ff0815bb3adf67c00bb1454f31b1f55d1d3da1cc90ad67c3718953aa54742577bc66b63958de83f9977c45679356748b22a45d9ee6646d3810be9cf7b0fdb9a38cd8f63bbaa803f7ca2802746ae26fa4c83424cc686068228ee04fac86980ec9e2f4cbb66efc2162b6ad102342430111ada24d0b35c8b6d489846160e798b41a80d936551fda7b83a9952da36a523f994d480123abcd253084b099938e505b6c75c0c0d4cccc80ea43aa754bae9e20fddd3b23096d209ed8fcdfdb53ebee0265ca5b1e415dfe2ad146aa2fb0d88cfffe751f51364c".decode("hex")

print(decrypt(out_decryptor, out1))
print(decrypt(in_decryptor, in1))
print(decrypt(out_decryptor, out2))
print(decrypt(in_decryptor, in2))
